package com.tqz.juc.atomic;

import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * <p>解决CAS下的ABA问题
 *
 * @author tianqingzhao
 * @since 2022/2/6 18:51
 */
public class AtomicStampedReferenceTest {
    
    static AtomicStampedReference<Integer> value = new AtomicStampedReference<>(1, 0);
    
    public static void main(String[] args) throws InterruptedException {
        Thread main = new Thread(() -> {
            int beforeReference = value.getReference();
            int beforeStamp = value.getStamp();
            System.out.println("主线程操作，初始值：" + beforeReference + "，版本号：" + beforeStamp);
            
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    
            // 其他线程修改过版本号之后，这个线程就会修改失败
            boolean success = value.compareAndSet(1, 2, beforeStamp, beforeStamp + 1);
            if (success) {
                System.out.println("主线程修改成功，修改之后的值：" + value.getReference() + "，版本号：" + value.getStamp());
            } else {
                System.out.println("主线程修改失败");
            }
        });
        
        Thread other = new Thread(() -> {
            value.compareAndSet(1, 2, value.getStamp(), value.getStamp() + 1);
            System.out.println("子线程操作修改之前的值：" + value.getReference() + "，版本号：" + value.getStamp());
    
            value.compareAndSet(2, 1, value.getStamp(), value.getStamp() + 1);
            System.out.println("子线程操作修改之后的值：" + value.getReference() + "，版本号：" + value.getStamp());
        });
        
        main.start();
        Thread.sleep(500);
        other.start();
    }
}
